﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace KingOfCSharp.iHunter.UI
{
    public partial class AddFilterWizard : Form
    {
        private LocalClient client;

        private UserControl currentControl;

        private UserControl[] wizardPages;

        private int currentWizardIndex;

        private string CustomFilterSettings;

        private IFilterProvider currentProvider = null;

        public AddFilterWizard(LocalClient client)
        {
            InitializeComponent();
            this.filterProviderSelectPanel1.filterProviderList1.listView1.DoubleClick += new EventHandler(listView1_DoubleClick);

            this.client = client;
            filterProviderSelectPanel1.filterProviderList1.Client = client;
            filterCommonSettingsPanel1.Client = client;
            this.currentControl = filterProviderSelectPanel1;
        }

        void listView1_DoubleClick(object sender, EventArgs e)
        {
            if (filterProviderSelectPanel1.filterProviderList1.listView1.SelectedItems.Count > 0)
            {
                buttonNext_Click(sender, e);
            }
        }

        public FilterInfo FilterInfo
        {
            get
            {
                return new FilterInfo()
                {
                    Guid = Guid.Empty,
                    Name = filterCommonSettingsPanel1.FilterName,
                    ProviderGuid = filterProviderSelectPanel1.filterProviderList1.SelectedProviderGuid,
                    FolderGuid = filterCommonSettingsPanel1.MoveToFolderGuid,
                    Settings = CustomFilterSettings,
                    Action = filterCommonSettingsPanel1.Action,
                };
            }
        }

        private string GetSettingsFromCurrentPage()
        {
            IXmlSerializable xmlControl = (IXmlSerializable)currentControl;

            using (TextWriter tw = new StringWriter())
            using (XmlWriter xmlWriter = new XmlTextWriter(tw))
            {
                try
                {
                    xmlControl.WriteXml(xmlWriter);
                }
                catch
                {
                    return null;
                }
                return tw.ToString();
            }
        }

        private void GotoCommonSettingsPage()
        {
            panel2.SuspendLayout();
            currentControl.Visible = false;
            currentControl = filterCommonSettingsPanel1;
            currentControl.Visible = true;
            buttonNext.Text = "&Finish";
            panel2.ResumeLayout(true);
        }

        private bool ValidateWizardPages(UserControl[] pages)
        {
            foreach (var page in pages)
            {
                if (!(page is IXmlSerializable))
                {
                    return false;
                }
                page.Visible = false;
                page.Dock = DockStyle.Fill;
            }
            return true;
        }

        private bool ValidateChannelCommonSettings()
        {
            if (filterCommonSettingsPanel1.FilterName == string.Empty)
            {
                MessageBox.Show("You should specify a name for this Filter.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        private void buttonNext_Click(object sender, EventArgs e)
        {
            if (currentControl == filterProviderSelectPanel1)
            {
                IFilterProvider provider = filterProviderSelectPanel1.filterProviderList1.SelectedProvider;
                if (provider == null)
                {
                    MessageBox.Show("Your have to select a Filter provider.", "Error!",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (provider != this.currentProvider)
                {
                    if (wizardPages != null)
                    {
                        foreach (var page in wizardPages)
                        {
                            page.Dispose();
                        }
                    }
                    wizardPages = provider.GetNewFilterWizardPages();
                    this.currentProvider = provider;
                }

                if (wizardPages == null)
                {
                    wizardPages = new UserControl[0];
                }

                if (!ValidateWizardPages(wizardPages))
                {
                    MessageBox.Show("This Filter provider is faulty.", "Error!",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                currentWizardIndex = 0;
                if (wizardPages.Length == 0)
                {
                    CustomFilterSettings = string.Empty;
                    GotoCommonSettingsPage();
                }
                else
                {
                    panel2.SuspendLayout();
                    currentControl.Visible = false;
                    currentControl = wizardPages[0];
                    panel2.Controls.AddRange(wizardPages);
                    currentControl.Visible = true;
                    panel2.ResumeLayout(true);
                }
                this.buttonBack.Enabled = true;
                return;
            }
            else if (currentControl == filterCommonSettingsPanel1)
            {
                if (ValidateChannelCommonSettings())
                {
                    this.DialogResult = DialogResult.OK;
                }
            }
            else if (currentWizardIndex == wizardPages.Length - 1)
            {
                CustomFilterSettings = GetSettingsFromCurrentPage();
                if (CustomFilterSettings != null)
                {
                    currentWizardIndex = wizardPages.Length;
                    GotoCommonSettingsPage();
                }
                return;
            }
            else
            {
                string settings = GetSettingsFromCurrentPage();
                if (settings == null)
                    return;

                IXmlSerializable xmlControl = (IXmlSerializable)wizardPages[currentWizardIndex + 1];
                using (TextReader tr = new StringReader(settings))
                using (XmlReader xr = new XmlTextReader(tr))
                {
                    try
                    {
                        xmlControl.ReadXml(xr);
                    }
                    catch
                    {
                        return;
                    }
                }

                currentControl.Visible = false;
                currentControl = wizardPages[++currentWizardIndex];
                currentControl.Visible = true;
            }
        }

        private void buttonBack_Click(object sender, EventArgs e)
        {
            if (currentWizardIndex == 0)
            {
                panel2.SuspendLayout();
                currentControl.Visible = false;
                currentControl = filterProviderSelectPanel1;
                currentControl.Visible = true;
                panel2.ResumeLayout(true);
                this.buttonBack.Enabled = false;
            }
            else if (currentControl == filterCommonSettingsPanel1)
            {
                currentControl.Visible = false;
                currentWizardIndex = wizardPages.Length - 1;
                currentControl = wizardPages[currentWizardIndex];
                this.buttonNext.Text = "&Next";
                currentControl.Visible = true;
            }
            else
            {
                currentControl.Visible = false;
                currentControl = wizardPages[--currentWizardIndex];
                currentControl.Visible = true;
            }
        }
    }
}
